String compression¶
Time: O(N); Space: O(1); easy
Given an array of characters, compress it in-place. The length after compression must always be smaller than or equal to the original array. Every element of the array should be a character (not int) of length 1. After you are done modifying the input array in-place, return the new length of the array.
Follow up:
Could you solve it using only O(1) extra space?
Example 1:
Input: chars = [“a”,“a”,“b”,“b”,“c”,“c”,“c”]
Output: 6, and the first 6 characters of the input array should be: [“a”,“2”,“b”,“2”,“c”,“3”]
Explanation:
“aa” is replaced by “a2”. “bb” is replaced by “b2”. “ccc” is replaced by “c3”.
Example 2:
Input: chars = [“a”]
Output: 1, and the first 1 characters of the input array should be: [“a”]
Explanation:
Nothing is replaced.
Example 3:
Input: chars = [“a”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”]
Output: 4, and the first 4 characters of the input array should be: [“a”,“b”,“1”,“2”].
Explanation:
Since the character “a” does not repeat, it is not compressed. “bbbbbbbbbbbb” is replaced by “b12”.
Notice each digit has it’s own entry in the array.
Notes:
All characters have an ASCII value in [35, 126].
1 <= len(chars) <= 1000.
[3]:
class Solution1(object):
def compress(self, chars):
"""
:type chars: List[str]
:rtype: int
"""
anchor, write = 0, 0
for read, c in enumerate(chars):
if read+1 == len(chars) or chars[read+1] != c:
chars[write] = chars[anchor]
write += 1
if read > anchor:
n, left = read-anchor+1, write
while n > 0:
chars[write] = chr(n%10+ord('0'))
write += 1
n //= 10
right = write-1
while left < right:
chars[left], chars[right] = chars[right], chars[left]
left += 1
right -= 1
anchor = read+1
return write
[7]:
s = Solution1()
chars = ["a","a","b","b","c","c","c"]
assert s.compress(chars) == 6
assert chars[:6] == ["a","2","b","2","c","3"]
chars = ["a"]
assert s.compress(chars) == 1
assert chars[:1] == ["a"]
chars = ["a","b","b","b","b","b","b","b","b","b","b","b","b"]
assert s.compress(chars) == 4
assert chars[:4] == ["a","b","1","2"]